package com.guowei.web.controller;

import com.guowei.web.domain.WebFileInfo;
import com.guowei.web.util.PathUtilFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class WebFileExplorerController {

    public static final String ROOT_NAME = "/explore";

    @RequestMapping(ROOT_NAME + "/**")
    public ModelAndView explore(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String requestURI = request.getRequestURI().substring(ROOT_NAME.length());
        if (!requestURI.endsWith("/")) {
            requestURI += "/";
        }
        return processFolder(requestURI, response);
    }

    private ModelAndView processFolder(String requestURI, HttpServletResponse response) throws IOException {
        File[] files;
        String currentPath;
        if (requestURI.equals("/")) {
            currentPath = "/";
            String os = System.getProperty("os.name").toLowerCase();
            if (os.contains("windows")) {
                files = File.listRoots();
            } else {
                files = new File(currentPath).listFiles();
            }
        } else {
            requestURI = URLDecoder.decode(requestURI, StandardCharsets.UTF_8.name());
            File path = new File(PathUtilFactory.instance().uri2Path(requestURI));
            currentPath = path.getAbsolutePath();
            if (path.isFile()) {
                processFile(path, response);
                return null;
            }
            files = path.listFiles();
        }
        List<WebFileInfo> webFileInfoList = new ArrayList<>();
        if (files != null) {
            int fileCount = 0;
            for (File file : files) {
                String absolutePath = file.getAbsolutePath();
                String uri = PathUtilFactory.instance().path2Uri(absolutePath);
                if (file.isFile()) {
                    webFileInfoList.add(new WebFileInfo(uri, file));
                    fileCount++;
                } else {
                    webFileInfoList.add(webFileInfoList.size() - fileCount, new WebFileInfo(uri, file));
                }
            }
        }
        Map<String, Object> model = new HashMap<>();
        model.put("ROOT_NAME", ROOT_NAME);
        model.put("currentPath", currentPath);
        model.put("webFileInfoList", webFileInfoList);
        return new ModelAndView("UI", model);
    }

    private void processFile(File path, HttpServletResponse response) throws IOException {
        String downloadName = new String(path.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        response.addHeader("Content-Disposition", "attachment;filename=" + downloadName + ";filename*=UTF-8''" + downloadName);
        response.addHeader("Content-Length", Long.toString(path.length()));
//        response.setContentType("application/octet-stream;charset=" + StandardCharsets.UTF_8.name());
        response.setContentType("application/x-download;charset=" + StandardCharsets.UTF_8.name());
        InputStream inputStream = new FileInputStream(path);
        int len;
        byte[] buffer = new byte[4096];
        while ((len = inputStream.read(buffer)) != -1) {
            response.getOutputStream().write(buffer, 0, len);
        }
        inputStream.close();
    }
}
